#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>

#ifndef __USE_MISC
#define __USE_MISC
#define __NO_DEFINE_MMAP_USE__
#endif

#include <sys/mman.h>

#ifdef __NO_DEFINE_MMAP_USE__
#undef __USE_MISC
#endif

#include <pthread.h>

int init_g = 0;
int uninit_g;

void code()
{
    ;
}

void* thread_run(void* args)
{
    (int*)args;
    int thread_int;
    char thread_char;
    printf("mmap: %p %p\n", &thread_int, &thread_char);
    return NULL;
}

int main(int argc, char* argv[], char* env[])
{
    //extern char** environ;

    for (int i = 0; env[i]; ++i)
        printf("%d : %p %s\n", i, env[i], env[i]);
    
    for (int i = 0; i < argc && argv[i]; ++i)
        printf("%d : %p %s\n", i, argv[i], argv[i]);

    int val_1 = 0, val_2;
    printf("stack: %p %p\n", &val_1, &val_2);
    
    pthread_t p;
    pthread_create(&p, NULL, thread_run, NULL);
    pthread_join(p, NULL);
    usleep(100000);
    
    char* str = (char*)mmap(NULL, 64, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_LOCKED | MAP_PRIVATE, -1, 0);
    printf("mmap: %p\n", str);
    munmap(str, 64);

    int* p1 = (int*)malloc(sizeof(int));
    int* p2 = (int*)malloc(sizeof(int));
    printf("heap: %p %p\n", p1, p2);
    free(p1);
    free(p2);

    printf("brk: %p\n", sbrk(0));

    static int init_st = 0;
    static int uninit_st;
    printf("uninit static: %p\n", &uninit_st);
    printf("init static: %p\n", &init_st);

    printf("uninit global: %p\n", &uninit_g);
    printf("init global: %p\n", &init_g);
    
    const char* str1 = "ABCDEF";
    const char* str2 = "123456";
    printf("only read: %p %p\n", str1, str2);

    printf("code: %p %p\n", main, code);

    return 0;
}
